

package msgcomm.transceivers;

import java.util.LinkedList;
import java.util.Queue;

import msgcomm.Hooks;
import msgcomm.Receiver;
import msgcomm.messages.Message;
import msgcomm.messages.Payload;
import msgcomm.messages.UnicastMessage;



/**
 * E' la classe base con cui e' possibile inviare e ricevere messaggi.
 * Offre un servizio unicast senza alcun tipo di ordinamento.
 * Estendendo questa classe e' possibile fornire altri tipi di servizi
 */
public class Unicast extends AbstractTransceiver {
	
	protected Unicast(String name, Queue<Message> msgQueue, Hooks reqList) {
		super(name, msgQueue, reqList);
	}
	
	protected Unicast(String name, Queue<Message> msgQueue) {
		this(name, msgQueue, null);
	}
	
	public Unicast(String name) {
		this(name, new LinkedList<Message>(), null);
	}
	
	public Unicast(String name, Hooks reqList) {
		this(name, new LinkedList<Message>(), reqList);
	}
	
	// CODA DEI MESSAGGI
	
	/**
	 * Invia un messaggio ad un destinatario
	 * @param destName nome del destinatario
	 * @param dest destinatario
	 * @param data payload del messaggio
	 * @throws Exception
	 */
	public void uniSend(String destName, Receiver dest, Payload data) throws Exception {
		Message msg = new Message(name,data);
		uniSend(destName,dest,msg);
	}
	
	
	protected void uniSend(String destName, Receiver dest, Message msg) throws Exception {
		log.printLogTh("uni-send " + msg + ": sto per inviare a \"" + destName + "\" il messaggio");
		dest.receive(msg);
		log.printLogTh("uni-send " + msg + ": inviato a \"" + destName + "\" il messaggio");
	}
	
	@Override
	public void receive(Message msg) {
		// consegno senza alcun ordinamento
		log.printLogTh("uni-receive " + msg);
		uniDeliver(msg);
	}


	protected void uniDeliver(Message msg) {
		if (! (msg instanceof UnicastMessage)) {
			throw new RuntimeException("Posso ricevere solo messaggi unicast");
		}
		log.printLogTh("uni-deliver " + msg);
		putMessage(msg);
	}
}
